<!--
 * @Author: wfl
 * @LastEditors: wfl
 * @description: 
 * @updateInfo: 本次更新内容：
 * @Date: 2021-03-17 14:23:59
 * @LastEditTime: 2021-04-29 16:50:23
-->
<template>
  <div class="upload_container">
    <a-row type="flex" justify="space-around" align="top">
      <a-col class="gutter-row" :flex="2" style="background: #fff">
        <a-upload-dragger
          name="file"
          class="upload-drag-box"
          :multiple="false"
          :action="$baseUrl.uploadUrl"
          :beforeUpload="beforeUpload"
          :customRequest="customRequest"
          :remove="removeFile"
        >
          <p class="ant-upload-drag-icon">
            <inbox-outlined></inbox-outlined>
          </p>
          <p class="ant-upload-text">点击选择或拖拽文件到此处上传</p>
        </a-upload-dragger>
      </a-col>
      <a-col class="gutter-row" :flex="4" style="background: #fff">
        <a-progress
          :stroke-color="{
            from: '#108ee9',
            to: '#87d068',
          }"
          :percent="cutRate"
          status="active"
        />
        <a-list
          item-layout="horizontal"
          :data-source="state.curtData"
          :locale="{
            emptyText: cutRate === 0 ? 'No Data' : '正在准备切片数据',
          }"
        >
          <template #renderItem="{ item }">
            <a-list-item>
              <a-list-item-meta :description="`${(item.chunk.size / 1024).toFixed(2)} kb`">
                <template #title>
                  <p>切片MD5：</p>
                  <p>{{ item.fileMd5No }}</p>
                </template>
                <template #avatar>
                  <a-avatar src="/@/assets/img/qiepian.png" />
                </template>
              </a-list-item-meta>
            </a-list-item>
          </template>
        </a-list>
        <a-button
          type="primary"
          class="mar-long-btn"
          ghost
          @click="cutFile"
          :disabled="cutRate === 100"
          block
          v-if="!state.finished"
        >{{ state.finished ? "切片完成" : "开始切片" }}</a-button>
        <a-button
          v-else
          type="primary"
          class="mar-long-btn"
          ghost
          @click="handClassify()"
          block
        >开始切片对比 - 区分已上传、未上传</a-button>
      </a-col>
    </a-row>
    <a-row type="flex" justify="space-around" align="top">
      <a-col :flex="1">
        <a-card title="未上传切片">
          <section class="wait-load">
            <a-spin :spinning="loading" tip="对比获取未上传切片">
              <a-list
                item-layout="horizontal"
                :data-source="state.waitLoadList"
                :locale="{
                  emptyText: '暂无数据',
                }"
              >
                <template #renderItem="{ item }">
                  <a-list-item>
                    <a-list-item-meta :description="`${(item.chunk.size / 1024).toFixed(2)} kb`">
                      <template #title>
                        <p>切片MD5：</p>
                        <p>{{ item.fileMd5No }}</p>
                      </template>
                      <template #avatar>
                        <a-avatar src="/@/assets/img/qiepian.png" />
                      </template>
                    </a-list-item-meta>
                  </a-list-item>
                </template>
              </a-list>
            </a-spin>
            <section>
              <a-progress
                :stroke-color="{
                  '0%': '#108ee9',
                  '100%': '#87d068',
                }"
                type="circle"
                :percent="uploadRate"
                status="active"
              />

              <a-button
                type="primary"
                ghost
                @click="uploadCutfile"
                :disabled="uploadRate === 100 && state.finished"
                v-if="uploadRate === 0 || uploadRate === 100"
                block
              >{{ (state.finished && uploadRate === 100) ? '已完成' : '上传切片' }}</a-button>
              <a-button
                v-else
                type="primary"
                ghost
                @click="stopUpload"
              >{{ handStop ? '继续上传' : '暂停上传' }}</a-button>
            </section>
          </section>
        </a-card>
      </a-col>
      <a-col :flex="1">
        <a-card title="已上传切片">
          <a-list
            item-layout="horizontal"
            :data-source="state.handLoadList"
            :locale="{
              emptyText: '暂无数据',
            }"
          >
            <template #renderItem="{ item }">
              <a-list-item>
                <a-list-item-meta :description="`${(item.chunk.size / 1024).toFixed(2)} kb`">
                  <template #title>
                    <p>切片MD5：</p>
                    <p>{{ item.fileMd5No }}</p>
                  </template>
                  <template #avatar>
                    <a-avatar src="/@/assets/img/qiepian.png" />
                  </template>
                </a-list-item-meta>
              </a-list-item>
            </template>
          </a-list>
        </a-card>
      </a-col>
    </a-row>
  </div>
</template>

<script lang="ts">
import { defineComponent, reactive, ref } from "vue";
import { VerticalAlignTopOutlined } from "@ant-design/icons-vue";
import BreakPointLoad from "/@/utils/cutrate/index";
import { uploadChunks } from "/@/utils/request/file-request";
import { IFileItem, IFileInfo, IState } from "/@/interface/if_file";
import { useFilechunkFilter } from '/@/hooks/useFilechunkFilter'
import { IRequest } from '/@/interface/if_rerquest'
import { fileApi } from '/@/network/api/file'
import { handPauseUpload } from '/@/utils/request/file-request'

export default defineComponent({
  name: "App",
  components: {
    VerticalAlignTopOutlined,
  },
  setup() {
    // 实例化切片类
    let cutLoad = new BreakPointLoad();
    // 是否暂停
    let handStop = ref(false);
    // 对比请求状态
    let loading = ref(false);
    // 切片数据
    const state: IState = reactive({
      curtData: [],
      finished: false,
      fileName: "",
      waitLoadList: [],
      handLoadList: []
    });
    // 切片进度
    let cutRate = ref<number>(0);
    // 上传进度
    let uploadRate = ref<number>(0);
    // 文件数据
    let fileData = ref<IFileItem | null>(null);
    // 删除文件
    const removeFile = (e: IFileInfo) => {
      // 置为原始状态 - 待优化
      cutRate.value = 0;
      uploadRate.value = 0;
      fileData.value = null;
      state.curtData = [];
      state.finished = false;
      state.fileName = "";
    };
    // 自定义上传
    const customRequest = (e: IFileInfo) => {
      // console.log('customRequest', e);
    };
    // 上传前
    const beforeUpload = (e: IFileItem) => {
      (fileData as unknown) = e;
      state.fileName = e.name || "file";
      // 不上传，等待切片后上传
      return false;
    };
    // 切片
    const cutFile = async () => {
      let chunkList = await cutLoad.inputChange(
        fileData,
        (list: any, len: number) => {
          // 已切片长度
          let listLen = list.length;
          // 切片进度
          cutRate.value = (len / listLen) * 100;
        }
      );
      // 是否完成切片
      state.finished = true;
      state.curtData = chunkList;
    };

    // 上传切片
    const uploadCutfile = () => {
      uploadChunks(state.waitLoadList, state.fileName, (percent: number) => {
        uploadRate.value = percent;
      });
    };

    // 切片对比
    const handClassify = async (auto: boolean = false) => {
      loading.value = true;
      let fileHash = '';
      const { curtData } = state;
      Array.isArray(curtData) && (fileHash = curtData[0].fileHash);
      let res: IRequest = await fileApi.findReadyChunk(fileHash);
      if (res.code) {
        const { waitList, handLoadList } = useFilechunkFilter(state.curtData, res.data);
        state.waitLoadList = waitList;
        state.handLoadList = handLoadList;
        console.log('auto', auto);
        auto && uploadCutfile();
      }
      loading.value = false;
    }

    // 暂停、继续上传 
    const stopUpload = () => {
      handStop.value = !handStop.value;
      // 暂停
      if (handStop.value) {
        handPauseUpload();
      } else {
        // 继续
        handClassify(true)
      }
    }

    return {
      fileData,
      cutRate,
      state,
      uploadRate,
      handStop,
      loading,
      beforeUpload,
      removeFile,
      customRequest,
      cutFile,
      uploadCutfile,
      handClassify,
      stopUpload,
    };
  },
});
</script>

<style lang="scss" scoped>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}

.mar-long-btn {
  width: calc(100% - 30px);
  position: relative;
  bottom: 5px;
  left: 15px;
}

.upload-drag-box {
  display: block;
  padding: 15px;
  height: 85%;
}

.flex-cloum {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-between;
}

.wait-load {
  display: grid;
  grid-template-columns: 48% 48%;
  grid-column-gap: 4%;

  section {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
  }
}
.upload_container {
  padding: 8px;
  width: 100vw;
  top: 50%;
  position: absolute;
  transform: translateY(-50%);
  min-height: 425px;

  .ant-row {
    height: 400px;
    margin: 25px 0;
    .ant-col {
      height: 100%;
      margin: 25px;
      padding: 0 15px;
    }
  }
  .ant-row,
  .ant-col {
    .ant-upload.ant-upload-drag {
      height: calc(100% - 50px);
    }
    .ant-list {
      height: 290px;
      margin: 9px 0;
      overflow-x: hidden;
      overflow-y: auto;
    }
  }
}
</style>
